home *** CD-ROM | disk | FTP | other *** search
/ Popular Request / By Popular Request (Arsenal Computer)(SysOptics Distribution System).ISO / amiga1 / chkdbl10.lha / CheckDouble.c < prev    next >
C/C++ Source or Header  |  1994-02-05  |  10KB  |  330 lines

  1. #ifndef DOS_EXALL_H
  2. #include <dos/exall.h>
  3. #endif
  4.  
  5. #include <proto/exec.h>
  6. #include <proto/dos.h>
  7. #include <proto/utility.h>
  8.  
  9. #include <string.h>
  10. #include <MyStartup.h>
  11.  
  12. #ifndef V39
  13. #ifndef CLIB_ALIB_PROTOS_H
  14. APTR LibAllocPooled( APTR poolHeader, unsigned long memSize );
  15. APTR LibCreatePool( unsigned long memFlags, unsigned long puddleSize,
  16.     unsigned long threshSize );
  17. void LibDeletePool( APTR poolHeader );
  18. void LibFreePooled( APTR poolHeader, APTR memory, unsigned long memSize );
  19. #endif   /* CLIB_ALIB_PROTOS_H */
  20. #else /* V39 only */
  21. #define LibAllocPooled AllocPooled
  22. #define LibCreatePool CreatePool
  23. #define LibDeletePool DeletePool
  24. #define LibFreePooled FreePooled
  25. #endif   /* V39 */
  26.  
  27. /***********************************************/
  28.  
  29. struct PathNode
  30.    {
  31.       BPTR Next;
  32.       BPTR DirLock;
  33.    };
  34.  
  35. struct FileNode
  36.    {
  37.       struct FileNode *Next;
  38.       long Type;
  39.       long Size;
  40.       UBYTE Printed;
  41.       char Filename[1];
  42.    };
  43.  
  44. /***********************************************/
  45.  
  46. #define BUFFER_SIZE 20000
  47.  
  48. static struct Library *UtilityBase;
  49.  
  50. static void *MemoryPool;
  51. static struct ExAllData *ExAllBuffer;
  52. static struct ExAllControl *ExAllControl;
  53.  
  54. static char FilePattern[32];
  55.  
  56. static struct FileNode *FileList;
  57.  
  58. static char Version[]="$VER: CheckDouble"
  59. #ifdef V39
  60.    "39"
  61. #endif
  62. " 1.0 (10.01.94) ⌐ 1994 Christian Stieber";
  63.  
  64. /***********************************************/
  65.  
  66. static void CloseAll(long Error, char *Header)
  67.  
  68. {
  69.    if (Error) PrintFault(Error,Header);
  70.  
  71.    if (MemoryPool) LibDeletePool(MemoryPool);
  72.    if (ExAllControl) FreeDosObject(DOS_EXALLCONTROL,ExAllControl);
  73.  
  74.    SetIoErr(Error);
  75.    exit(Error ? RETURN_FAIL : RETURN_OK);
  76. }
  77.  
  78. /***********************************************/
  79.  
  80. static void ReadDir(BPTR DirLock)
  81.  
  82. {
  83.    static struct FileNode *LastNode;
  84.  
  85.    char Filename[1024];
  86.    int More;
  87.  
  88.    if (!NameFromLock(DirLock,Filename,sizeof(Filename))) CloseAll(IoErr(),NULL);
  89.    ExAllControl->eac_LastKey=0;
  90.    do
  91.       {
  92.          More=ExAll(DirLock,ExAllBuffer,BUFFER_SIZE,ED_PROTECTION,ExAllControl);
  93.          if (More || IoErr()==ERROR_NO_MORE_ENTRIES)
  94.             {
  95.                if (ExAllControl->eac_Entries)
  96.                   {
  97.                      struct ExAllData *Data;
  98.                      Data=ExAllBuffer;
  99.                      do
  100.                         {
  101.                            struct FileNode *NewNode;
  102.                            if (!AddPart(Filename,Data->ed_Name,sizeof(Filename))) CloseAll(IoErr(),Filename);
  103.                            if (!(NewNode=LibAllocPooled(MemoryPool,sizeof(struct FileNode)+strlen(Filename)))) CloseAll(IoErr(),NULL);
  104.                            NewNode->Type=Data->ed_Type;
  105.                            NewNode->Size=Data->ed_Size;
  106.                            NewNode->Printed=FALSE;
  107.                            strcpy(NewNode->Filename,Filename);
  108.                            NewNode->Next=NULL;
  109.                            if (LastNode)
  110.                               {
  111.                                  LastNode->Next=NewNode;
  112.                               }
  113.                            else
  114.                               {
  115.                                  FileList=NewNode;
  116.                               }
  117.                            LastNode=NewNode;
  118.                            *PathPart(Filename)='\0';
  119.                            Data=Data->ed_Next;
  120.                         }
  121.                      while (Data);
  122.                   }
  123.             }
  124.       }
  125.    while (More);
  126.    if (IoErr()!=ERROR_NO_MORE_ENTRIES) CloseAll(IoErr(),Filename);
  127. }
  128.  
  129. /***********************************************/
  130.  
  131. static void ReadDirs(void)
  132.  
  133. {
  134.    struct CommandLineInterface *CLI;
  135.  
  136.    if (CLI=Cli())
  137.       {
  138.          struct PathNode *CurrentNode;
  139.          CurrentNode=BADDR(CLI->cli_CommandDir);
  140.          while (CurrentNode)
  141.             {
  142.                if (CheckSignal(SIGBREAKF_CTRL_C)) CloseAll(ERROR_BREAK,NULL);
  143.                ReadDir(CurrentNode->DirLock);
  144.                CurrentNode=BADDR(CurrentNode->Next);
  145.             }
  146.       }
  147. }
  148.  
  149. /***********************************************/
  150.  
  151. static ULONG /* __saveds */ __asm MatchFunc(register __a1 struct ExAllData *Data)
  152.  
  153. {
  154.    if (Data->ed_Type>=0) return FALSE;   /* ignore directories */
  155.    if (Data->ed_Prot & (FIBF_EXECUTE | FIBF_READ)) return FALSE;   /* read and execute permission required */
  156.    if (Data->ed_Size<16) return FALSE;   /* file too short */
  157.    return TRUE;
  158. }
  159.  
  160. static struct Hook MatchHook=
  161.    {
  162.       {NULL,NULL},MatchFunc,NULL,NULL
  163.    };
  164.  
  165. /***********************************************/
  166.  
  167. static void InitStuff(void)
  168.  
  169. {
  170.    if (!(UtilityBase=OpenLibrary("utility.library",37))) exit(100);
  171.  
  172.    if (!(MemoryPool=LibCreatePool(0,50*1024,50*1024)) ||
  173.        !(ExAllBuffer=LibAllocPooled(MemoryPool,BUFFER_SIZE)) ||
  174.        !(ExAllControl=AllocDosObject(DOS_EXALLCONTROL,NULL)) ||
  175.        (ParsePatternNoCase("~(#?.info)",FilePattern,sizeof(FilePattern))==-1))
  176.       {
  177.          CloseAll(IoErr(),NULL);
  178.       }
  179.    ExAllControl->eac_MatchString=FilePattern;
  180.    ExAllControl->eac_MatchFunc=&MatchHook;
  181. }
  182.  
  183. /***********************************************/
  184.  
  185. static void FindDuplicateNames(void)
  186.  
  187. {
  188.    struct FileNode *CurrentNode;
  189.  
  190.    CurrentNode=FileList;
  191.    while (CurrentNode)
  192.       {
  193.          if (CheckSignal(SIGBREAKF_CTRL_C)) CloseAll(ERROR_BREAK,NULL);
  194.          if (!CurrentNode->Printed)
  195.             {
  196.                struct FileNode *t;
  197.                int FirstMatch;
  198.                char *CurrentFile;
  199.  
  200.                FirstMatch=TRUE;
  201.                CurrentFile=FilePart(CurrentNode->Filename);
  202.                t=CurrentNode;
  203.                while (t=t->Next)
  204.                   {
  205.                      if (!Stricmp(CurrentFile,FilePart(t->Filename)))
  206.                         {
  207.                            t->Printed=TRUE;
  208.                            if (FirstMatch)
  209.                               {
  210.                                  VPrintf("Duplicate commandname \x22%s\x22:\n   ",&CurrentFile);
  211.                                  PutStr(CurrentNode->Filename);
  212.                                  PutStr("\n");
  213.                                  FirstMatch=FALSE;
  214.                               }
  215.                            PutStr("   ");
  216.                            PutStr(t->Filename);
  217.                            PutStr("\n");
  218.                         }
  219.                   }
  220.             }
  221.          else
  222.             {
  223.                CurrentNode->Printed=FALSE;
  224.             }
  225.          CurrentNode=CurrentNode->Next;
  226.       }
  227. }
  228.  
  229. /***********************************************/
  230.  
  231. static long *ReadFile(struct FileNode *FileNode)
  232.  
  233. {
  234.    BPTR FileHandle;
  235.    long *Memory;
  236.    long Error;
  237.  
  238.    if (CheckSignal(SIGBREAKF_CTRL_C)) CloseAll(ERROR_BREAK,NULL);
  239.    if (!(Memory=LibAllocPooled(MemoryPool,(FileNode->Size+3)&~3))) CloseAll(IoErr(),FileNode->Filename);
  240.    Memory[((FileNode->Size+3)>>2)-1]=0;
  241.    if (!(FileHandle=Open(FileNode->Filename,MODE_OLDFILE))) CloseAll(IoErr(),FileNode->Filename);
  242.    if (Read(FileHandle,Memory,FileNode->Size)!=FileNode->Size)
  243.       {
  244.          Error=IoErr();
  245.       }
  246.    else
  247.       {
  248.          Error=0;
  249.       }
  250.    Close(FileHandle);
  251.    if (Error) CloseAll(Error,FileNode->Filename);
  252.    return Memory;
  253. }
  254.  
  255. /***********************************************/
  256.  
  257. static void FindDuplicateFiles(void)
  258.  
  259. {
  260.    struct FileNode *CurrentNode;
  261.  
  262.    CurrentNode=FileList;
  263.    while (CurrentNode)
  264.       {
  265.          if (CheckSignal(SIGBREAKF_CTRL_C)) CloseAll(ERROR_BREAK,NULL);
  266.          if (CurrentNode->Type!=ST_LINKFILE && !CurrentNode->Printed)
  267.             {
  268.                long *CurrentFile;
  269.                struct FileNode *t;
  270.                int FirstMatch;
  271.  
  272.                CurrentFile=NULL;
  273.                t=CurrentNode;
  274.                FirstMatch=TRUE;
  275.                while (t=t->Next)
  276.                   {
  277.                      if (t->Type!=ST_LINKFILE && t->Size==CurrentNode->Size)
  278.                         {
  279.                            long *tFile;
  280.                            long i;
  281.                            int Identical;
  282.  
  283.                            if (!CurrentFile) CurrentFile=ReadFile(CurrentNode);
  284.                            tFile=ReadFile(t);
  285.                            Identical=TRUE;
  286.                            for (i=0; Identical && i<(CurrentNode->Size+3)>>2; i++)
  287.                               {
  288.                                  if (CurrentFile[i]!=tFile[i])
  289.                                     {
  290.                                        Identical=FALSE;
  291.                                     }
  292.                               }
  293.                            LibFreePooled(MemoryPool,tFile,(t->Size+3)&~3);
  294.                            if (Identical)
  295.                               {
  296.                                  if (FirstMatch)
  297.                                     {
  298.                                        PutStr("Identical files:\n   ");
  299.                                        PutStr(CurrentNode->Filename);
  300.                                        PutStr("\n");
  301.                                        FirstMatch=FALSE;
  302.                                     }
  303.                                  PutStr("   ");
  304.                                  PutStr(t->Filename);
  305.                                  PutStr("\n");
  306.                                  t->Printed=TRUE;
  307.                               }
  308.                         }
  309.                   }
  310.                if (CurrentFile) LibFreePooled(MemoryPool,CurrentFile,(CurrentNode->Size+3)&~3);
  311.             }
  312.          CurrentNode=CurrentNode->Next;
  313.       }
  314. }
  315.  
  316. /***********************************************/
  317.  
  318. void main(void)
  319.  
  320. {
  321.    if (CommandLineLength)
  322.       {
  323.          InitStuff();
  324.          ReadDirs();
  325.          FindDuplicateNames();
  326.          FindDuplicateFiles();
  327.          CloseAll(0,NULL);
  328.       }
  329. }
  330.